import * as fs from 'fs';
import { JavaParser } from '../utils/JavaParser.js';

export interface BatchExtractionResult {
  success: boolean;
  message: string;
  filesModified: string[];
  extractedMethods: Array<{
    startLine: number;
    endLine: number;
    confidence: 'high' | 'medium' | 'low';
    suggestedName: string;
    reason: string;
  }>;
  suggestions: string[];
  errors?: string[];
}

/**
 * 智能批量提取器 - 基于已修复的extract_method实现安全的批量重构
 */
export class SmartBatchExtractor {

  /**
   * 智能分析大方法并建议安全的提取策略
   */
  async suggestExtractions(filePath: string, methodName: string, maxLines: number = 80): Promise<BatchExtractionResult> {
    const result: BatchExtractionResult = {
      success: false,
      message: '',
      filesModified: [],
      extractedMethods: [],
      suggestions: [],
      errors: []
    };

    try {
      console.error(`[SmartBatchExtractor] 开始分析方法: ${methodName} in ${filePath}`);
      
      const content = fs.readFileSync(filePath, 'utf-8');
      
      // 1. 找到目标方法
      const methodBounds = JavaParser.findMethodBounds(content, methodName);
      if (!methodBounds) {
        result.errors?.push(`未找到方法: ${methodName}`);
        result.message = `未找到方法: ${methodName}`;
        return result;
      }

      console.error(`[SmartBatchExtractor] 方法边界:`, methodBounds);

      // 2. 检查方法是否需要重构
      if (methodBounds.nonEmptyLines <= maxLines) {
        result.success = true;
        result.message = `方法 ${methodName} 只有 ${methodBounds.nonEmptyLines} 行，无需重构`;
        return result;
      }

      // 3. 分析可提取的代码块
      const extractableBlocks = this.analyzeExtractableBlocks(content, methodBounds);
      console.error(`[SmartBatchExtractor] 找到 ${extractableBlocks.length} 个可提取的代码块`);

      // 4. 根据置信度排序并生成建议
      const sortedBlocks = extractableBlocks.sort((a, b) => {
        const confidenceOrder = { high: 3, medium: 2, low: 1 };
        return confidenceOrder[b.confidence] - confidenceOrder[a.confidence];
      });

      result.suggestions = [
        `🔍 方法 ${methodName} 有 ${methodBounds.nonEmptyLines} 行（超过 ${maxLines} 行限制）`,
        `📋 找到 ${extractableBlocks.length} 个可提取的代码块：`,
        ''
      ];

      for (let i = 0; i < sortedBlocks.length && i < 5; i++) {
        const block = sortedBlocks[i];
        const confidenceIcon = block.confidence === 'high' ? '🟢' : 
                              block.confidence === 'medium' ? '🟡' : '🟠';
        
        result.suggestions.push(
          `${confidenceIcon} 第${block.startLine}-${block.endLine}行 (${block.endLine - block.startLine + 1}行)`,
          `   建议方法名: ${block.suggestedName}`,
          `   置信度: ${block.confidence}`,
          `   原因: ${block.reason}`,
          ''
        );
      }

      result.suggestions.push(
        '💡 建议手动提取步骤：',
        '1️⃣ 从置信度最高的代码块开始',
        '2️⃣ 使用 extract_method 工具逐个提取',
        '3️⃣ 每次提取后测试编译',
        '4️⃣ 重复直到方法长度满足要求'
      );

      result.success = true;
      result.message = `分析完成，发现 ${extractableBlocks.length} 个可提取的代码块`;
      result.extractedMethods = sortedBlocks;

    } catch (error) {
      result.errors?.push(`分析失败: ${error}`);
      result.message = `分析失败: ${error}`;
      console.error(`[SmartBatchExtractor] 错误:`, error);
    }

    return result;
  }

  /**
   * 分析可提取的代码块
   */
  private analyzeExtractableBlocks(content: string, methodBounds: any): Array<{
    startLine: number;
    endLine: number;
    confidence: 'high' | 'medium' | 'low';
    suggestedName: string;
    reason: string;
  }> {
    const lines = content.split('\n');
    const blocks: Array<{
      startLine: number;
      endLine: number;
      confidence: 'high' | 'medium' | 'low';
      suggestedName: string;
      reason: string;
    }> = [];

    // 在方法体内查找可提取的块
    for (let i = methodBounds.bodyStartLine; i < methodBounds.bodyEndLine - 1; i++) {
      const blockInfo = this.analyzeCodeBlock(lines, i, methodBounds.bodyEndLine - 1);
      if (blockInfo) {
        blocks.push(blockInfo);
      }
    }

    return blocks;
  }

  /**
   * 分析单个代码块
   */
  private analyzeCodeBlock(lines: string[], startLine: number, maxLine: number): {
    startLine: number;
    endLine: number;
    confidence: 'high' | 'medium' | 'low';
    suggestedName: string;
    reason: string;
  } | null {
    
    const line = lines[startLine - 1];
    if (!line || line.trim() === '' || line.trim().startsWith('//')) {
      return null;
    }

    // 1. 检查注释块 - 高置信度
    if (line.trim().startsWith('//')) {
      const comment = line.trim().replace(/^\/\/\s*/, '');
      if (comment.length > 5) {
        const blockEnd = this.findLogicalBlockEnd(lines, startLine, maxLine);
        if (blockEnd > startLine + 2) {
          return {
            startLine: startLine + 1,
            endLine: blockEnd,
            confidence: 'high',
            suggestedName: this.generateMethodName(comment),
            reason: `注释明确描述了功能: "${comment}"`
          };
        }
      }
    }

    // 2. 检查for循环 - 中等置信度
    if (line.trim().startsWith('for (')) {
      const blockEnd = this.findBraceBlockEnd(lines, startLine, maxLine);
      if (blockEnd > startLine + 2) {
        return {
          startLine: startLine + 1,
          endLine: blockEnd,
          confidence: 'medium',
          suggestedName: 'processLoopOperation',
          reason: 'for循环可以提取为单独的方法'
        };
      }
    }

    // 3. 检查if语句块 - 中等置信度
    if (line.trim().startsWith('if (')) {
      const blockEnd = this.findBraceBlockEnd(lines, startLine, maxLine);
      if (blockEnd > startLine + 3) {
        return {
          startLine: startLine + 1,
          endLine: blockEnd,
          confidence: 'medium',
          suggestedName: 'handleCondition',
          reason: 'if语句块逻辑相对独立'
        };
      }
    }

    // 4. 检查try-catch块 - 高置信度
    if (line.trim().startsWith('try {')) {
      const blockEnd = this.findTryCatchBlockEnd(lines, startLine, maxLine);
      if (blockEnd > startLine + 3) {
        return {
          startLine: startLine + 1,
          endLine: blockEnd,
          confidence: 'high',
          suggestedName: 'executeWithErrorHandling',
          reason: 'try-catch块是完整的错误处理逻辑单元'
        };
      }
    }

    return null;
  }

  /**
   * 找到逻辑块的结束位置
   */
  private findLogicalBlockEnd(lines: string[], startLine: number, maxLine: number): number {
    let endLine = startLine;
    
    // 查找下一个空行或注释作为块的结束
    for (let i = startLine; i < maxLine && i < lines.length; i++) {
      const line = lines[i];
      if (line.trim() === '' || line.trim().startsWith('//')) {
        break;
      }
      endLine = i + 1;
    }
    
    return Math.min(endLine, startLine + 10); // 限制最大块大小
  }

  /**
   * 找到大括号块的结束位置
   */
  private findBraceBlockEnd(lines: string[], startLine: number, maxLine: number): number {
    let braceCount = 0;
    let foundOpenBrace = false;
    
    for (let i = startLine - 1; i < maxLine && i < lines.length; i++) {
      const line = lines[i];
      for (const char of line) {
        if (char === '{') {
          braceCount++;
          foundOpenBrace = true;
        } else if (char === '}') {
          braceCount--;
          if (foundOpenBrace && braceCount === 0) {
            return i + 1;
          }
        }
      }
    }
    
    return startLine;
  }

  /**
   * 找到try-catch块的结束位置
   */
  private findTryCatchBlockEnd(lines: string[], startLine: number, maxLine: number): number {
    // 简化实现：找到对应的catch或finally
    for (let i = startLine; i < maxLine && i < lines.length; i++) {
      const line = lines[i].trim();
      if (line.startsWith('} catch') || line.startsWith('} finally') || line === '}') {
        return i + 1;
      }
    }
    return startLine;
  }

  /**
   * 根据注释生成方法名
   */
  private generateMethodName(comment: string): string {
    // 清理注释并转换为驼峰命名
    const cleaned = comment.replace(/[^\w\s]/g, '').trim();
    const words = cleaned.split(/\s+/).filter(w => w.length > 0);
    
    if (words.length === 0) return 'extractedMethod';
    
    // 转换为驼峰命名
    const methodName = words[0].toLowerCase() + 
      words.slice(1).map(w => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join('');
    
    return methodName.length > 30 ? 'extractedMethod' : methodName;
  }
}